package com.ruoyi.quartz.domain;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
//import com.ruoyi.quartz.task.ProtocolPacket;
//import com.ruoyi.quartz.task.ProtocolPacket;
import io.swagger.annotations.ApiModelProperty;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import java.util.*;

import java.text.SimpleDateFormat;
import java.util.List;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
//import com.example.SurfData;
/**
 * 推送模式对象 offset
 * 
 * @author ruoyi
 * @date 2024-03-18
 */
public class Sjkpacket extends BaseEntity
{
    private static final long serialVersionUID = 1L;

    /** $column.columnComment */
    @ApiModelProperty("id")
    @Excel(name = "序号", cellType = Excel.ColumnType.NUMERIC, type = Excel.Type.EXPORT)
    private Integer ID;

    /** 推送模式（0-正常模式 1-应急模式）
工作模式分为：正常模式和应急模式，默认为正常模式。 */
    @ApiModelProperty("推送模式")
    @Excel(name = "推送模式", readConverterExp = "0=-正常模式,1=-应急模式", cellType = Excel.ColumnType.NUMERIC, type = Excel.Type.EXPORT)
    private Integer pushMode;

    /** 推送时间间隔（min）
正常模式上报时间间隔：北斗定位终端和其他地灾类传感器均为5min。
北斗定位终端为1min，其他地灾类传感器为5min。 */
    @ApiModelProperty("推送时间间隔")
    @Excel(name = "推送时间间隔",  cellType = Excel.ColumnType.NUMERIC, type = Excel.Type.EXPORT)
    private Integer timeInterval;

    /** $column.columnComment */
    @ApiModelProperty("网络地址")
    @Excel(name = "网络地址",  cellType = Excel.ColumnType.STRING, type = Excel.Type.EXPORT)
    private String ip;

    /** $column.columnComment */
    @ApiModelProperty("网络端口")
    @Excel(name = "网络端口",  cellType = Excel.ColumnType.STRING, type = Excel.Type.EXPORT)
    private Integer port;

    /** $column.columnComment */
    @ApiModelProperty("修改时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Excel(name = "修改时间",  cellType = Excel.ColumnType.NUMERIC, type = Excel.Type.EXPORT)
    private Date modifyTime;

    /** $column.columnComment */
    @ApiModelProperty("修改起始时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Excel(name = "修改起始时间",  cellType = Excel.ColumnType.NUMERIC, type = Excel.Type.EXPORT)
    private Date beginModifyTime;

    /** $column.columnComment */
    @ApiModelProperty("修改截至时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Excel(name = "修改截至时间",  cellType = Excel.ColumnType.NUMERIC, type = Excel.Type.EXPORT)
    private Date endModifyTime;

    /** $column.columnComment */
    @ApiModelProperty("发送数据")
    @JsonFormat(pattern = "[68.39]")
    @Excel(name = "发送数据",  cellType = Excel.ColumnType.NUMERIC, type = Excel.Type.EXPORT)
    private String buffer_sjk;

//    // 声明全局变量 buffer_sjk
//    private byte[] buffer_sjk;

    public void setID(Integer ID) 
    {
        this.ID = ID;
    }

    public Integer getID() 
    {
        return ID;
    }
    public void setPushMode(Integer pushMode) 
    {
        this.pushMode = pushMode;
    }

    public Integer getPushMode() 
    {
        return pushMode;
    }
    public void setTimeInterval(Integer timeInterval) 
    {
        this.timeInterval = timeInterval;
    }

    public Integer getTimeInterval() 
    {
        return timeInterval;
    }
    public void setIp(String ip) 
    {
        this.ip = ip;
    }

    public String getIp() 
    {
        return ip;
    }
    public void setPort(Integer port) 
    {
        this.port = port;
    }

    public Integer getPort() 
    {
        return port;
    }
    public void setBeginModifyTime(Date beginModifyTime)
    {
        this.beginModifyTime = beginModifyTime;
    }

    public Date getBeginModifyTime()
    {
        return beginModifyTime;
    }
    public void setEndModifyTime(Date endModifyTime)
    {
        this.endModifyTime = endModifyTime;
    }

    public Date getEndModifyTime()
    {
        return endModifyTime;
    }
    public void setModifyTime(Date modifyTime)
    {
        this.modifyTime = modifyTime;
    }

    public Date getModifyTime()
    {
        return modifyTime;
    }

    public String getBufferSjk()
    {
        return buffer_sjk;
    }



//
class SurfData {
    private float xecef;
    private float yecef;

    public SurfData(float xecef, float yecef) {
        this.xecef = xecef;
        this.yecef = yecef;
    }

    public float getXECEF() {
        return xecef;
    }

    public float getYECEF() {
        return yecef;
    }
}

    public interface CoordinateData {
        float getXECEF();
        float getYECEF();
    }

    // 定义协议数据结构
     public static class ProtocolPacket {
        // 帧头 (2字节)
        short frameHeader;
        // 帧类型 (1字节)
        byte frameType;
        // 数据帧长度 (2字节)
        short dataFrameLength;
        // 采集设备编号 (8字节)
        long deviceSN;
        // 时间戳 (8字节)
        long timestamp;
        // 数据项数量 (1字节)
        byte dataItemCount;
        // 数据项内容 (N * 10字节)
        byte[] dataItems;
        // 滚动校验 (1字节)
        byte rollingCheck;
        // 累加校验 (1字节)
        byte checksum;

        public ProtocolPacket(short frameHeader, byte frameType, short dataFrameLength,
                              long deviceSN, long timestamp, byte dataItemCount,
                              byte[] dataItems, byte rollingCheck) {
            this.frameHeader = frameHeader;
            this.frameType = frameType;
            this.dataFrameLength = dataFrameLength;
            this.deviceSN = deviceSN;
            this.timestamp = timestamp;
            this.dataItemCount = dataItemCount;
            this.dataItems = dataItems;
            this.rollingCheck = rollingCheck;
            this.checksum = 0;
        }
    }
    public static byte[] packExample() {


        byte[] dataItems = {
                (byte) 0x44, (byte) 0x2F, (byte) 0xE1, (byte) 0xA4, (byte) 0x5C, (byte) 0x97, (byte) 0x52, (byte) 0x24, (byte) 0x01, (byte) 0x00, // 数据项1
                (byte) 0x45, (byte) 0x2F, (byte) 0x71, (byte) 0x3D, (byte) 0x52, (byte) 0x41, (byte) 0x47, (byte) 0x2F, (byte) 0x00, (byte) 0x00  // 数据项2
        };

        ProtocolPacket packet = new ProtocolPacket(
                (short) 0x5753, // 帧头
                (byte) 0x01,    // 帧类型
                (short) 63,     // 数据帧长度
                610100122060001L, // 采集设备编号
                0L,             // 时间戳
                (byte) 2,       // 数据项数量
                dataItems,
                (byte) 198      // 滚动校验
        );

        byte[] buffer_sjk = new byte[1024];
        int bufferLen = generatePacket(packet, buffer_sjk);

        // 打印生成的数据包
        System.out.println("Generated packet:");
        for (int i = 0; i < bufferLen; i++) {
            System.out.printf("%02X ", buffer_sjk[i]);
        }
        System.out.println("buffer_sjk-数据");
        System.out.println(buffer_sjk);
        return buffer_sjk;
    }
//    public static byte[] buffer_sjk = new byte[1024];

    public static int generatePacket(ProtocolPacket packet, byte[] bufferList) {
        int offset = 0;

//        byte[] buffer_sjk = new byte[buffer_sjk.size()];
//        // 将List<Byte>转换为byte[]
//        for (int i = 0; i < buffer_sjk.size(); i++) {
//            buffer_sjk[i] = buffer_sjk.get(i);
//        }

        // 写入帧头 (小端模式)
        bufferList[offset++] = (byte) (packet.frameHeader & 0xFF);
        bufferList[offset++] = (byte) ((packet.frameHeader >> 8) & 0xFF);

        // 写入帧类型
        bufferList[offset++] = packet.frameType;

        // 写入数据帧长度 (小端模式)
        bufferList[offset++] = (byte) (packet.dataFrameLength & 0xFF);
        bufferList[offset++] = (byte) ((packet.dataFrameLength >> 8) & 0xFF);

        // 写入采集设备编号 (小端模式)
        for (int i = 0; i < 8; i++) {
            bufferList[offset++] = (byte) ((packet.deviceSN >> (8 * i)) & 0xFF);
        }

        // 写入时间戳 (小端模式)
        for (int i = 0; i < 8; i++) {
            bufferList[offset++] = (byte) ((packet.timestamp >> (8 * i)) & 0xFF);
        }

        // 写入数据项数量
        bufferList[offset++] = packet.dataItemCount;

        // 写入数据项内容
        System.arraycopy(packet.dataItems, 0, bufferList, offset, packet.dataItemCount * 10);
        offset += packet.dataItemCount * 10;

        // 写入滚动校验
        bufferList[offset++] = packet.rollingCheck;

        // 计算并写入累加校验
        byte checksum = 0;
        for (int i = 0; i < offset; i++) {
            checksum += bufferList[i];
        }
        bufferList[offset++] = checksum;

        // 将修改后的buffer写回List<Byte>
//        for (int i = 0; i < bufferList.length; i++) {
//            bufferList.set(i, bufferList[i]);
//        }


        // 添加调试信息
        System.out.printf("Generated data length: %d\n", offset);
//        return buffer_sjk;
        return offset;
    }
//
//    List<String> list = new ArrayList<>(Arrays.asList(
//            "MONITORPOINTCODE=12",
//            "DEVICECODE=31",
//            "mountPoint=123",
//            "MONITORPOINTCODE=12"
//    ));


//    没有处理日期

    public static byte[] generateDataItems(List<String> list) {
        if (list == null || list.isEmpty()) return new byte[0];

        byte[] result = new byte[list.size() * 10];
        int offset = 0;

        Map<String, Short> sensorTypes = new HashMap<>();
        sensorTypes.put("X", (short) 10101);
        sensorTypes.put("Y", (short) 10102);
        sensorTypes.put("Z", (short) 10103);
        sensorTypes.put("STATUS", (short) 10104);
        sensorTypes.put("EPOCH", (short) 10105);

        SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
        dateFormat.setTimeZone(TimeZone.getTimeZone("CST"));

        for (String str : list) {
            String[] parts = str.split("=", 2);
            if (parts.length != 2) continue;

            String key = parts[0].toUpperCase();
            Short type = sensorTypes.get(key);
            if (type == null) continue;

            // Write sensor type (2 bytes, little-endian)
            result[offset++] = (byte) (type & 0xFF);
            result[offset++] = (byte) ((type >> 8) & 0xFF);

            try {
                if ("EPOCH".equals(key)) {
                    long timestamp = dateFormat.parse(parts[1]).getTime();
                    for (int i = 0; i < 8; i++) {
                        result[offset++] = (byte) ((timestamp >> (8 * i)) & 0xFF);
                    }
                } else {
                    int bits = Float.floatToIntBits(Float.parseFloat(parts[1]));
                    for (int i = 0; i < 4; i++) {
                        result[offset++] = (byte) ((bits >> (8 * i)) & 0xFF);
                    }
                    offset += 4; // Skip 4 bytes for 6-byte total
                }
            } catch (Exception e) {
                offset -= 2; // Rewind if parsing fails
            }
        }

        return offset == result.length ? result : Arrays.copyOf(result, offset);
    }

    // 从 List<surfDataList> 生成数据项字节数组
//    public static  byte[] generateDataItems(List<String> list) {
//        if (list == null || list.isEmpty()) {
//            return new byte[0];
//        }
//
//        byte[] result = new byte[list.size() * 10];
//        int offset = 0;
//
//        for (String str : list) {
//            // Example: Parse "KEY=VALUE" and encode
//            String[] parts = str.split("=");
//            if (parts.length == 2) {
//                String key = parts[0];
//                String value = parts[1];
//                // Custom encoding logic (this is just an example)
//                float val = Float.parseFloat(value); // Assuming value is numeric
//                int bits = Float.floatToIntBits(val);
//                for (int i = 0; i < 4; i++) {
//                    result[offset++] = (byte) ((bits >> (8 * i)) & 0xFF);
//                }
//                // Fill remaining 6 bytes with placeholder data
//                for (int i = 0; i < 6; i++) {
//                    result[offset++] = (byte) 0;
//                }
//            }
//        }
//
//        return result;
//    }



    // 示例：打包数据
//    public static byte[] packExample() {
//        byte[] dataItems = {
//                (byte) 0x44, (byte) 0x2F, (byte) 0xE1, (byte) 0xA4, (byte) 0x5C, (byte) 0x97, (byte) 0x52, (byte) 0x24, (byte) 0x01, (byte) 0x00, // 数据项1
//                (byte) 0x45, (byte) 0x2F, (byte) 0x71, (byte) 0x3D, (byte) 0x52, (byte) 0x41, (byte) 0x47, (byte) 0x2F, (byte) 0x00, (byte) 0x00  // 数据项2
//        };
//
//        // 生成数据项字节数组
////        byte[] dataItemsBytes = generateDataItems(dataList);
//
//       ProtocolPacket packet = new ProtocolPacket(
//                (short) 0x5753, // 帧头
//                (byte) 0x01,    // 帧类型
//                (short) 63,     // 数据帧长度
//                610100122060001L, // 采集设备编号
//                0L,             // 时间戳
//                (byte) 2,       // 数据项数量
//                dataItems,
//                (byte) 198      // 滚动校验
//        );
//
////        byte[] buffer_sjk = new byte[1024];
////        int bufferLen = generatePacket(packet, buffer_sjk);
//
//        // 初始化一个足够大的List<Byte>
//        List<Byte> bufferList = Arrays.asList(new byte[1024]);
//        int bufferLen = generatePacket(packet, bufferList);
//
//
//        // 打印生成的数据包
//        System.out.println("Generated packet:");
//        for (int i = 0; i < bufferLen; i++) {
//            System.out.printf("%02X ", bufferList.get[i]);
//        }
//        System.out.println();
////        System.out.println(buffer_sjk);
////        return dataList;
//    }
// Sensor type names map
private static final Map<Short, String> SENSOR_TYPE_NAMES = new HashMap<>();
    static {SENSOR_TYPE_NAMES.put((short) 10101, "X (RTK X)");
        SENSOR_TYPE_NAMES.put((short) 10102, "Y (RTK Y)");
        SENSOR_TYPE_NAMES.put((short) 10103, "Z (RTK Z)");
        SENSOR_TYPE_NAMES.put((short) 10104, "STATUS");
        SENSOR_TYPE_NAMES.put((short) 10105, "EPOCH");
    }

    public static String parseAndPrintDataItems(byte[] data) {
        if (data == null || data.length == 0) {
            return "No data to parse.\n";
        }

        ByteBuffer buffer = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzz");
        dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));

        StringBuilder output = new StringBuilder();
        output.append("Parsing generateDataItems output:\n");
        output.append("Total bytes: ").append(data.length).append("\n");

        int offset = 0;
        while (offset + 10 <= data.length) {
            short sensorType = buffer.getShort(offset);
            offset += 2;

            String typeName = SENSOR_TYPE_NAMES.getOrDefault(sensorType, "Unknown Type (" + sensorType + ")");
            output.append(String.format("Offset %d: Sensor Type: %s (0x%04X)\n", offset - 2, typeName, sensorType));

            if (sensorType == 10105) {
                long timestamp = buffer.getLong(offset);
                offset += 8;
                String dateStr = dateFormat.format(new Date(timestamp));
                output.append(String.format("  Value: %d ms (%s)\n", timestamp, dateStr));
            } else {
                float value = buffer.getFloat(offset);
                offset += 4;
                output.append(String.format("  Value: %.6f\n", value));
                offset += 4;
            }
        }

        if (offset < data.length) {
            output.append("Warning: Incomplete data at end, ").append(data.length - offset).append(" bytes remaining.\n");
        }

        System.out.println("打印结果"+ output.toString());
        return output.toString();
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
            .append("ID", getID())
            .append("pushMode", getPushMode())
            .append("timeInterval", getTimeInterval())
            .append("ip", getIp())
            .append("port", getPort())
            .append("modifyTime", getModifyTime())
            .append("beginModifyTime", getBeginModifyTime())
            .append("endModifyTime", getEndModifyTime())
            .toString();
    }

    // 提供获取全局变量 buffer_sjk 的方法
//    public byte[] getBuffer_sjk() {
//        return buffer_sjk;
//    }
}
